package com.example.mq.mqserver.core;

import lombok.Data;

import java.io.Serializable;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ws
 * Date: 2023-09-30
 * Time: 14:40
 */
/*
* 表示一个要传递的消息
* 此处的 Message对象需要能够在网络传输，并且写入文件
* 所以需要能够实现序列化和反序列化
 */
@Data
public class Message implements Serializable {// 标准库提供给的序列化（二进制），json 本质上是文本格式（文本类型的数据）
    // 核心的两个部分
    // 属性部分 (使用 BasicProperties 来存储)
    private BasicProperties basicProperties = new BasicProperties();// 这里 new 是为了防止空指针
    // 正文部分(二进制数据)
    private byte[] body;

    // 下面的属性是辅助使用的
    // Message 后续会存储到文件中（如果持久化的话）
    // 一个文件存储多个消息，根据以下的属性定位到具体的位置
    // [offsetBegin, offsetEnd)
    // 这两个属性存在的目的是为了让内存中的 Message对象，能够快速地找到对应硬盘上的 Message对象 的位置
    // 所以不需要被序列化保存到文件中，因为消息一旦被写入文件，位置就固定了，并不需要单独储存
    // transient 关键字，表示不需要序列化
    private transient long offsetBegin = 0;// Message数据的开头距离文件开头的偏移（字节）
    private transient long offsetEnd = 0;// Message 数据的结尾距离文件开头的偏移（字节）
    // 表示该 Message 在文件中是否有效（逻辑删除）
    // 0x1 表示有效，0x0 表示无效（因为存储在文件中，所以 byte 比 boolean 使用方便）
    private byte isValid = 0x1;


    /*
     * 创建一个工厂方法，封装创建 Message对象 的过程
     * 这个方法中创建的 Message对象，会自动生成唯一的 MessageId
     */
    public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body) {
        Message message = new Message();
        if (basicProperties != null) {// 属性不为 null，才能赋值
            message.setBasicProperties(basicProperties);
        }
        // 以最新传进来的 routingKey 为主
        message.basicProperties.setRoutingKey(routingKey);
        // 随机生成UUID
        // 使用 "M-" + UUID 作为唯一标志符（M 是区分其他 id 的前缀）
        message.setMessageId("M-" + UUID.randomUUID().toString());
        message.body = body;
        // 此处只设置 basicProperties 和 body 这两个核心部分
        // 而 offsetBegin，offsetEnd，isValid，则是消息持久化的时候才会用到，在消息写入文件之前在进行设置
        // 此处仅仅是创建一个 Message对象
        return message;
    }


    /*
    * 方便直接拿到消息的 ID
     */
    public String getMessageId() {
        return basicProperties.getMessageId();
    }

    public void setMessageId(String messageId) {
        basicProperties.setMessageId(messageId);
    }

    /*
     * 同理为了方便拿到 routingKey
     */
    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }

    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    /*
     * 持久化的 deliverMode
     */
    public int getDeliverMode() {
        return basicProperties.getDeliverMode();
    }

    public void setDeliverMode(int deliverMode) {
        basicProperties.setDeliverMode(deliverMode);
    }

}
